/*
 * Created on Aug 26, 2008
 * (c) 2008 by Tenereillo, Inc.
 */
package ro.letsdoitromania.forms;

import java.util.Vector;
import javax.microedition.lcdui.*;
import ro.letsdoitromania.LDIRCanvas;
import ro.letsdoitromania.LDIRMidlet;
import ro.letsdoitromania.LDIRSettings;
import com.mgmaps.app.APPCommands;
import com.mgmaps.app.SerialCall;
import com.mgmaps.gps.GPS;
import com.mgmaps.tools.UITools;
import com.mgmaps.utils.ExtLogger;
import com.mgmaps.utils.IBluetooth;
import com.mgmaps.utils.LS;
// import com.mgmaps.utils.LogForm;

public class SettingsForm implements CommandListener, ItemStateListener {
  private Form form;
  
  private ChoiceGroup cgLanguage;
  private ChoiceGroup cgGPS;
  private TextField tfUser;
  private TextField tfPass;
  
  private IBluetooth bt;
  private String tempGPS;
  
  private static SettingsForm instance;
  private String language;
  
  public static SettingsForm getInstance() {
    if (instance == null)
      instance = new SettingsForm();
    return instance;
  }
  
  private SettingsForm() {
    language = LDIRSettings.language;
  }
  
  private void resetForm() {
    cgLanguage = null;
    cgGPS = null;
    tfUser = null;
    tfPass = null;
    bt = null;
  }

  public void show() {
    if (language != LDIRSettings.language)
      resetForm();
    
    final Vector itemVector = new Vector();
    
    if (cgLanguage == null)
      cgLanguage = new ChoiceGroup(LS.get("app.settings.language"), Choice.POPUP, 
          LS.getLangDescs(), null);
    itemVector.addElement(cgLanguage);
    
    if (LDIRSettings.hasBT) {
      if (cgGPS == null)
        cgGPS = new ChoiceGroup(LS.get("app.settings.gps"), Choice.POPUP,
            new String[] { LS.get("app.gps.internal"), LS.get("app.gps.bluetooth") }, null);
      itemVector.addElement(cgGPS);
    }
    
    if (tfUser == null)
      tfUser = new TextField(LS.get("app.settings.username"), LDIRSettings.username,
          30, TextField.ANY);
    else
      tfUser.setString(LDIRSettings.username);
    tfUser.setInitialInputMode("MIDP_LOWERCASE_LATIN");
    itemVector.addElement(tfUser);
    
    if (tfPass == null)
      tfPass = new TextField(LS.get("app.settings.password"), LDIRSettings.password,
          30, TextField.ANY | TextField.PASSWORD);
    else
      tfPass.setString(LDIRSettings.password);
    tfPass.setInitialInputMode("MIDP_LOWERCASE_LATIN");
    itemVector.addElement(tfPass);
    
    final Item[] items = new Item[itemVector.size()];
    itemVector.copyInto(items);
    itemVector.removeAllElements();

    form = UITools.buildForm(form, LS.get("app.settings.title"), items,
        new Command[] { APPCommands.instance.okCommand, APPCommands.instance.backCommand }, this);
    
    /*
    // show log
    if (LDIRSettings.LOG_AVAILABLE)
      form.addCommand(APPCommands.instance.viewLogCommand);
    */
    
    int ind = LS.getLanguageIndex(LDIRSettings.language);
    if (ind < 0)
      ind = 0;
    cgLanguage.setSelectedIndex(ind, true);
    ind = GPS.getGPSReceiverIndex(LDIRSettings.gpsDevice);
    if (ind < 0 || ind > 1)
      ind = 0;
    if (cgGPS != null)
      cgGPS.setSelectedIndex(ind, true);

    if (LDIRSettings.hasBT)
      form.setItemStateListener(this);

    tempGPS = LDIRSettings.gpsDevice;
    
    Display.getDisplay(LDIRMidlet.instance).setCurrent(form);    
  }

  public void commandAction(Command cmd, Displayable disp) {
    if (cmd == APPCommands.instance.btCompleteCommand)
      cmdBlueDiscComplete();
    else if (cmd == APPCommands.instance.btCancelCommand)
      cmdBlueDiscCancel();
    /*
    else if (cmd == APPCommands.instance.viewLogCommand)
      Display.getDisplay(LDIRMidlet.instance).setCurrent(new LogForm(LDIRMidlet.instance, form));
    */
    else if (cmd == APPCommands.instance.okCommand) {
      // save language
      String[] ln = LS.getLangNames();
      LDIRSettings.language = ln[cgLanguage.getSelectedIndex()];
      LS.setLanguage(LDIRSettings.language);
      
      int index = GPS.getGPSReceiverIndex(tempGPS);
      if (index < 0 || index > 1) {
        index = 0;
        tempGPS = "Internal";
      }
      LDIRSettings.gpsDevice = tempGPS;
      LDIRCanvas.instance.gps.setReceiver(true);
      
      // save settings
      LDIRSettings.save();
      LDIRCanvas.instance.notifyGPSUpdate(false);
      
      // save username and password
      final String oldusername = LDIRSettings.username;
      final String oldpassword = LDIRSettings.password;
      LDIRSettings.username = tfUser.getString().trim();
      LDIRSettings.password = tfPass.getString().trim();
      if (!oldusername.equals(LDIRSettings.username) || !oldpassword.equals(LDIRSettings.password))
        LDIRSettings.usersalt = "";
      
      LDIRCanvas.instance.loadNewLanguage();
      LDIRSettings.save();
      
      // show alert for the user to restart the application.
      Display.getDisplay(LDIRMidlet.instance).setCurrent(LDIRCanvas.instance);
      SerialCall.instance.show(SerialCall.SC_ALERT, LS.get("app.settings.saved"), LS.get("app.settings.savedmsg"));
      // PendingForm.getInstance().show(LDIRCanvas.instance, LS.get("app.settings.saved"), LS.get("app.settings.savedmsg"), 
      //     new Command[] { APPCommands.instance.okCommand });
    }
    else
      Display.getDisplay(LDIRMidlet.instance).setCurrent(LDIRCanvas.instance);
  }

  /**
   * Called when an item state has changed.
   * 
   * @param item item changed
   * @see javax.microedition.lcdui.ItemStateListener#itemStateChanged(javax.microedition.lcdui.Item)
   */
  public void itemStateChanged(Item item) {
    if (item == cgGPS) {
      int index = cgGPS.getSelectedIndex();
      if (index == 0)
        tempGPS = "Internal";
      else {
        // bluetooth discovery object
        if (bt == null) {
          try {
            bt = (IBluetooth) Class.forName("com.mgmaps.utils.Bluetooth").newInstance();
            bt.setListener(this);
          }
          catch (Exception ex) {
            ExtLogger.handle(ex, false, "Error instantiating Bluetooth class");
            return;
          }
        }
        
        bt.showGPS();
        return;
      }
    }
  }
  
  /**
   * Bluetooth discovery complete. We should never be called if
   * bluetooth is not available.
   */
  private void cmdBlueDiscComplete() {
    // get the first discovered service
    String tempURL = "";
    try {
      String url = bt.getURL();
      if (url != null) {
        tempURL = url;
        ExtLogger.debug("Bluetooth URL is " + url);
      }
    }
    catch (Exception ex) {
      ExtLogger.handle(ex, false, "Could not connect to bluetooth device");
    }

    tempGPS = tempURL;

    // continue with the same action as bluedisc/cancel
    cmdBlueDiscCancel();
  }
  
  /**
   * Cancel bluetooth discovery.
   */
  private void cmdBlueDiscCancel() {
    int ind = GPS.getGPSReceiverIndex(tempGPS);
    if (ind < 0 || ind > 1)
      ind = 0;

    if (cgGPS != null)
      cgGPS.setSelectedIndex(ind, true);

    Display.getDisplay(LDIRMidlet.instance).setCurrent(form);
  }
}
